<?php

declare (strict_types=1);

namespace app\common\service\user;

use app\common\exception\AdminException;
use app\common\repository\user\UserRepository;
use app\common\service\BaseService;
use app\common\repository\user\WithdrawalApplyRepository;
use app\common\service\WeChatTransferService;
use think\facade\Config;
use app\common\service\wechat\WechatTransfer;
use think\facade\Db;
use think\facade\Log;

class WithdrawalApplyService extends BaseService
{
    public function __construct(WithdrawalApplyRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * 获取列表
     *
     * @param array $params
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     */
    public function getList(array $params = []): array
    {
        [$page, $pageSize] = $this->getPaginationParams();
        $where = [];
        if(!empty($params['user_id'])){
            $where['user_id'] = $params['user_id'];
        }
        return $this->repository->paginate($where, ['create_time' => 'desc'], $page, $pageSize);
    }

    /**
     * 提现
     *
     * @param $user_id
     * @param $gear_id
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function create($user_id, $gear_id)
    {
        Log::info('提现金额' . json_encode($gear_id));

        $withdrawalGearService = app()->make(WithdrawalGearService::class);
        $gearInfo = $withdrawalGearService->getInfo($gear_id);

        $auto = $gearInfo['auto_approve'] == 1 ? true : false;

        if ($gearInfo['daily_limit'] !== 0) {
            $count = Db::name('withdrawal_apply')->where(['user_id' => $user_id])->whereDay('create_time')->count();
            if ($count >= $gearInfo['daily_limit']) {
                throw new AdminException('当日提现次数已上限');
            }
        }

        if ($gearInfo['amount'] <= 0) {
            throw new AdminException('请输入合法提现金额');
        }
        $feeAmount = $gearInfo['amount'] * (get_config('app.withdrawal_fee') / 100); // 手续费金额
        $feeRate = get_config('app.withdrawal_fee'); // 手续费比例

        $actualAmount = $gearInfo['amount'] - $feeAmount; // 实际到账金额 = 提现金额 - 手续费
        $gold = $gearInfo['amount'] * get_config('app.rate'); // 金币

        if ($actualAmount < 0) {
            throw new AdminException('手续费过高，实际到账金额不能为负');
        }

        $userService = app()->make(UserService::class);
        $userInfo = $userService->getInfo($user_id);
        if (!$userInfo) {
            throw new AdminException('用户不存在');
        }

        if ($gold > $userInfo['balance']) {
            throw new AdminException('提现失败：金币不足');
        }

        $data = [
            'user_id' => $user_id,
            'open_id' => $userInfo['open_id'],
            'username' => $userInfo['username'],
            'apply_time' => time(),
            'order_no' => get_id(),
            'status' => 0,
            'fee' => $feeAmount, // 手续费金额
            'fee_rate' => $feeRate, // 手续费比例
            'amount' => $gearInfo['amount'], // 金额
            'actual_amount' => $actualAmount, // 实际到账金额
            'gold' => $gold,// 金币
        ];

        return $this->transaction(function () use ($data, $userService, $auto) {
            $this->repository->save($data);
            Db::name('user')->where('id', $data['user_id'])->dec('balance', $data['gold'])->update();

            if ($auto) {
                // 发起微信支付
                $transferData = [
                    'out_no' => $data['order_no'],
                    'scene_id' => '1005',
                    'openid' => $data['open_id'],
                    'amount' => $data['actual_amount'] * 100, // 分
                ];

                $result = WechatTransfer::toBalance($transferData);

                // 检查状态是否为WAIT_USER_CONFIRM
                if ($result['state'] === 'WAIT_USER_CONFIRM') {
                    // 创建成功，可引导用户确认收款
                    return [
                        'code' => 1,
                        'msg' => '创建成功，请引导用户确认收款',
                        'data' => $result
                    ];
                } else {
                    // 其他状态处理
                    return [
                        'code' => 2,
                        'msg' => '创建成功',
                        'data' => $result
                    ];
                }
            }
            return true;
        });
    }

    /**
     * 微信提现
     *
     * @param $user_id
     * @param $order_no
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function wechatTransfer($user_id, $order_no)
    {
        $data = $this->repository->getOne(['order_no' => $order_no])->toArray();
        if(!$data){
            throw new AdminException('提现失败');
        }
        if($data['status'] != 3){ // 状态3通常代表“待打款”
            throw new AdminException('提现失败');
        }
        return $this->transaction(function () use ($user_id, $order_no, $data) {
            // 发起微信支付
            $transferData = [
                'out_no' => $data['order_no'],
                'scene_id' => '1005',
                'openid' => $data['open_id'],
                'amount' => $data['actual_amount'] * 100, // 分
            ];

            $result = WechatTransfer::toBalance($transferData);

            // 修改提现状态
            $this->repository->update(['status' => 1], ['order_no' => $data['order_no']]);

            // 检查状态是否为WAIT_USER_CONFIRMa
            if ($result['state'] === 'WAIT_USER_CONFIRM') {
                // 创建成功，可引导用户确认收款
                return [
                    'code' => 1,
                    'msg' => '创建成功，请引导用户确认收款',
                    'data' => $result
                ];
            } else {
                // 其他状态处理
                return [
                    'code' => 2,
                    'msg' => '创建成功',
                    'data' => $result
                ];
            }
        });
    }

    /**
     * 修改
     *
     * @param array $data
     * @param $where
     * @return \app\common\model\BaseModel|bool|int
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function update(array $data, $where): \app\common\model\BaseModel|bool|int
    {
        $arr['status'] = $data['status'];
        $arr['remark'] = $data['remark'];
        if($arr['status'] == 2) {
            $data = $this->repository->getOne($where)->toArray();
            // 拒绝返回金币给用户
            Db::name('user')->where('id', $data['user_id'])->inc('balance', $data['amount'] * 1000)->update();
        }
        return $this->repository->update($arr, $where);
    }

    /**
     * 获取详情
     *
     * @param $where
     * @return \app\common\model\BaseModel|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getInfo($where): ?\app\common\model\BaseModel
    {
        return $this->repository->getOne($where);
    }

    /**
     * 删除
     *
     * @param $where
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function delete($where): bool
    {
        return $this->repository->delete([
            'id' => $where['id']
        ]);
    }
}